<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试</title>
</head>
<body>
<button onclick="handlePushState()">点击pushState</button>
<br/>
<button onclick="showLength()">打印length</button>
</body>
<script>
    console.log('页面加载......');//初始化执行一次
    let index = 0;
    function handlePushState(){
        let state = {state:'handlePushState'};
        window.history.pushState(state,'测试first','first'+ index++ +'.html');
    }
    function showLength(){
        console.log("window.history.length:"+window.history.length);//window.history.length:10
    }
</script>
<script>
    /**
     * 上面是一个完整的html文件，文件名为 first.html。 把该文件放到web服务器上，从浏览器访问。如果是直接从本地磁盘打开，
     * 文件中的js代码执行会报错误。在一个新的浏览器窗口访问该first.html。 首先会执行 console.log('页面加载......')。
     * 这时执行 打印length 按钮，显示为1，注意如果在ie或chrome的新的浏览器窗口打开，值可能为2，因为它们的窗口会加载系统默认的一个页面，
     * 不是一个空白的窗口。这时我们每点击一下 点击pushState 按钮，发现浏览器的地址会发生变化，先后变为first1.html , first2.html,
     * first3.html, .......，并且通过点击 打印length按钮 发现，弹出的值加1. 这说明每调用一次pushState方法，history中就会新增加
     * 一条url记录。
     */

    /**
     * 我们先来解释下pushState方法，该方法有三个参数：
     1）第一个参数是个js对象，可以放任何的内容，可以在onpopstate事件中（后面介绍）获取到便于做相应的处理。
     2）第二个参数是个字符串，目前好像没有起作用，可以传个空串。
     3）第三个参数是个字符串，就是保存到history中的url。

     结合例子的代码和输出可以看出，调用pushState方法的作用，就是相当于打开一个新页面，把当前页面作为历史记录，
     而当前的地址栏显示的是pushState方法中的url（这里是first.html）。但是与普通的打开一个新页面不同。浏览器
     将不会在调用pushState()方法后加载这个url，也就是说即使你写一个错误的url，也不会报错。可以这么理解，当我
     们在一个新的浏览器窗口打开 first.html后，点击n次pushState按钮后，history对象中存在这样的一个ulr列表。
     first.html(第1个url)----> first1.html（第2个url）.......->first?.html（第n个url）----->firstn.html(当前页面的url)。
     这时我们需要点击浏览器上的回退按钮n次，才能将浏览器上的地址退回到 first.html。而且无论是在点击pushState按钮 或点击回退按钮的过程中发现，
     console.log('页面加载......')方法根本没有被触发，也就是说整个过程浏览器的页面内容都没有发生变化，变化的只是地址信息。
     这也进一步说明，pushState只是将当前页面保存到history的历史记录中（并作为最近的一个记录），并且将当前浏览器的地址栏改为参数url的指定的值，
     但并不会加载它。这点与普通的通过链接打开或浏览器地址输入url完全不一样。
     */

    /**
     * 到了这里我们可以想象一下文章开头提出的问题了，如果我们在页面中执行一个ajax操作，当操作成功（如更新页面的局部内容）后，我们通过代码调用pushState方法，
     * 设置一个新的url，这样看上去就像发起了一个全新的请求，实际上只是个ajax操作。这时回退按钮也能用了，问题仅仅这样，回退按钮点了也没有任何反应。如果我们能
     * 通过代码，来响应这个回退按钮触发的事件，在事件中让界面恢复到ajax请求之前的界面，问题不就解决了吗？得确如此，解决思路就是上面说的。
     */

    /**
     * replaceState方法与pushState类似，同样有三个参数。区别在于，replaceState()是用来修改history对象中记录的当前页面的信息，它不是新建一个记录。
     * 如果将上面例子中的 代码 history.pushState({}, "nettle","first"+(index++)+".html"); 中的pushState改为replaceState，其它代码都不动。
     * 这时我们点击pushState按钮后，看到的现象是一样的，地址栏的地址不断变化，页面内容不变。但我们点击 打印length 按钮，发现history中的记录数不变。这说明
     * replaceState只是改变当前页面在history对象中的记录信息；而pushState是会产生一个新记录作为当前记录，把当前页面作为历史的记录保存。我们再来看
     * 下window对象的popstate事件，当进行页面的前进或回退时，会触发该事件，并且在事件响应函数中通过 history.state 可以获取到 pushState方法和
     * replaceState方法中第一个参数指定的对象。
     */
</script>
</html>